classdef Stop2
%STOP2 Summary of this class goes here
%   Detailed explanation goes here

   properties
       H =[];
       Min;
       Max;
       TotalSweep;
       X;
       Y;
       Z = 1.82;
       Range;
   end

   methods
       %constructor for a stop. It takes a list of headings, and an x and y
       %coordiante. First it determines the range of rotation which is the
       %beginign and ending poitn of angles. A sort of min and max. It does
       %this by rotating the arc such that the arc does not cross the 180
       %to -180 gap. Without this gap it simply uses the min/max functions
       %to determine the beginign and ending points. It then rotates those
       %values back to normal. Determines a coordiante not existent in the
       %arc list, and then roates this value to the -180 to 180 gap.
       function this = Stop2(h,x,y)
           this.H = h;
           this.X = x;
           this.Y = y;
           
           b = -180;
           e = 180;
           
           val = this.GetRotatePoint();
           if val == 1000
               this.Range = 360;               
           else
               shift = 180 - val;
               h2 = h +shift;
               
               for j=1:length(h2)
                   if h2(j)>180
                       h2(j) = h2(j)-360;
                   end
               end
               
               b = min(h2);
               e = max(h2);
               
               
               this.Range = e-b;
               
               
               b = b-shift;
               e = e-shift;
           end
           this.Min = b;
           this.Max = e;


           this.TotalSweep = this.CalculateSweep();
       end
       
       
       %cycles through a set of heading coordiantes and determines how to
       %rate things properly. Finds a coordinate that does not exist in the
       %arc coordinates. Iterates through all 360 degrees on INTERVALS
       %size. Once it finds a value non existent in teh list, it returns
       %it.CAN NOT DEAL WITH ROATATIONS OF OVER 345 DEGREES. IN THESE CASES
       %IT WILL SIMPLY DETERMINE 360 AS THE RANGE. This gives a ~5% error in
       %~.01% of the cases so it is acceptable.
       function val = GetRotatePoint(this)
           val = 1000;
           INTERVALS = 7.5;
           for j=(-180/INTERVALS):(180/INTERVALS)
              found = 0;
              for i=1:length(this.H)
                  if this.H(i) > j*INTERVALS-INTERVALS && ...
                     this.H(i) < j*INTERVALS+INTERVALS
                     found =1;
                     break;
                  end  
              end
              if ~found
                val = j*INTERVALS;
                return
              end
           end
       end
       
       %Rotates through a set of heading coordinates. Uses these values to
       %determien the absolute change between every consecutive
       %coordinates. Adds these up to determine a total amount of rotation.
       %Deals with teh gap from -180 to 180 properly.
       function ts = CalculateSweep(this)
          h = this.H;
          angle_sum = 0;
          previous_angle = h(1);
          for j=2:length(h)
              current_angle = h(j);
              if (previous_angle <-170 && current_angle > 170) || ...
                 (previous_angle > 170 && current_angle < -170 )
                    angle_sum = angle_sum + (180-abs(previous_angle)) + (180-abs(current_angle));
              elseif (previous_angle < 15 && previous_angle >0 && ...
                  current_angle >-15 && current_angle < 0 ) || ...
                 (previous_angle > -15 && previous_angle <0 && ...
                  current_angle <15 && current_angle > 0 ) 
                    angle_sum = angle_sum + abs(previous_angle) + abs(current_angle);
              else
                    angle_sum = angle_sum + abs(current_angle - previous_angle);
              end
              previous_angle = current_angle;
          end
          ts = angle_sum;
       end
       
       %easy accessor function to avoid division by 0.
       function r = GetRatio(this)
           if this.Range == 0
               r = NaN;
           elseif this.TotalSweep == 0
               r = NaN;
           else
               r = this.TotalSweep/this.Range;
           end
       end          
   end
end 
